#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/wait.h>
int factorial(int n) {
	    if (n == 1)
	       return 1;
	        return factorial(n - 1) * n;
}
int fibonacci(int n) {

	    if (n == 1 || n == 2)
		            return 1;
	        return fibonacci(n - 1) + fibonacci(n - 2);
}
int main(int argc, char *argv[]) {

	    if (argc != 3) {

		            fprintf(stderr, "Usage: %s x y\n", argv[0]);
			            exit(EXIT_FAILURE);

		 }
	        int x = atoi(argv[1]);
	        int y = atoi(argv[2]);
	        int pipe_fx[2], pipe_fy[2];
		if (pipe(pipe_fx) == -1 || pipe(pipe_fy) == -1) {
			            perror("pipe");
			            exit(EXIT_FAILURE);}
    pid_t pid_a = fork();

        if (pid_a == 0) {

		        close(pipe_fx[0]);
		        close(pipe_fy[0]);
			close(pipe_fy[1]);
		        int result = factorial(x);
		      if (write(pipe_fx[1], &result, sizeof(result)) != sizeof(result)) {
				 perror("write fx failed");
			                exit(EXIT_FAILURE);
		      }

	 close(pipe_fx[1]);
	 exit(EXIT_SUCCESS);
			 }

pid_t pid_b = fork();

    if (pid_b == 0) {

	            close(pipe_fy[0]);
		    close(pipe_fx[0]);
		    close(pipe_fx[1]);
		    int result = fibonacci(y);
		    if (write(pipe_fy[1], &result, sizeof(result)) != sizeof(result)) {
			    perror("write fy failed");
			    exit(EXIT_FAILURE);										
		    }
		    close(pipe_fy[1]);
		    exit(EXIT_SUCCESS);
			 }
pid_t pid_c = fork();

    if (pid_c == 0) {

	            close(pipe_fx[1]);
		    close(pipe_fy[1]);
	            int fx, fy;
		    ssize_t bytes;
	            bytes = read(pipe_fx[0], &fx, sizeof(fx));
		    if (bytes != sizeof(fx)) {
			    if (bytes < 0)
				    perror("read fx failed");
			    else
				    fprintf(stderr, "Incomplete read for fx\n");
              			    exit(EXIT_FAILURE);
		    }
		    bytes = read(pipe_fy[0], &fy, sizeof(fy));
		    if (bytes != sizeof(fy)) {
			    if (bytes < 0)
				    perror("read fy failed");

			    else
				    fprintf(stderr, "Incomplete read for fy\n");
			    exit(EXIT_FAILURE);
		    }
		    printf("f(%d, %d) = %d\n", x, y, fx + fy);
		    close(pipe_fx[0]);
		    close(pipe_fy[0]);
		    exit(EXIT_SUCCESS);
    }
close(pipe_fx[0]);
close(pipe_fx[1]);
close(pipe_fy[0]);
close(pipe_fy[1]);
waitpid(pid_a, NULL, 0);

    waitpid(pid_b, NULL, 0);

        waitpid(pid_c, NULL, 0);



	    return 0;

	    }
